from common_import import *
from statsmodels.tsa.stattools import acf
import statsmodels.api as sm
import datetime


plt.rcParams["font.sans-serif"] = ["SimHei"]  # 使用黑体
plt.rcParams["axes.unicode_minus"] = False  # 解决负号显示问题


def cal_period():
    data = tool.get_np("total_daily_quantity.csv")["total_quantity"]
    # 使用 STL 分解
    stl = sm.tsa.seasonal_decompose(data, period=7, model="additive")
    fig = stl.plot()
    fig.set_size_inches(13, 6)

    # 设置横轴的日期刻度
    start_date = datetime.datetime(2020, 7, 1)
    end_date = datetime.datetime(2023, 6, 30)
    date_range = pd.date_range(start=start_date, end=end_date, periods=len(data))

    # 获取所有子图，并设置横轴刻度
    for ax in fig.get_axes():
        ax.set_xticks(np.arange(0, len(data), step=len(data) // 10))  # 10个主要刻度
        ax.set_xticklabels(
            date_range.strftime("%Y-%m-%d")[:: len(data) // 10], rotation=0
        )
    mydraw.show_or_print("stl_day.png")

    # 提取季节性成分作为周期性
    seasonal = stl.seasonal
    # 计算零交点的位置
    zero_crossings = np.where(np.diff(np.sign(seasonal)))[0]
    # 计算波峰和波谷之间的周期
    peak_intervals = np.diff(zero_crossings)

    # 取平均波峰间距作为周期估计
    if len(peak_intervals) > 1:
        estimated_period = (
            np.mean(peak_intervals) * 2
        )  # 乘以2是因为零交点只记录了波峰到波谷或波谷到波峰的间隔
    else:
        estimated_period = "无法识别周期，数据可能无明显周期性"

    print(f"识别的周期为: {estimated_period} 个时间单位")

    # # 绘制季节性成分
    # plt.figure(figsize=(10, 6))
    # plt.plot(seasonal)
    # plt.title("周期性成分 (Seasonal Component)")
    # plt.xlabel("时间 (Time)")
    # plt.ylabel("周期性")
    # plt.show()


def cal_period_month():
    data = tool.get_np("total_monthly_quantity.csv")["total_quantity"]
    # 创建日期索引
    dates = pd.date_range(start="2020-07", end="2023-07", freq="M")

    # 将数据转换为带日期索引的 Pandas Series
    print(len(data))
    data_series = pd.Series(data, index=dates)

    # 使用 STL 分解，手动指定周期
    stl = sm.tsa.seasonal_decompose(data_series, period=12, model="additive")
    fig = stl.plot()
    fig.set_size_inches(13, 6)
    mydraw.show_or_print("stl_month.png")
    # 提取季节性成分作为周期性
    seasonal = stl.seasonal

    # 计算零交点的位置
    zero_crossings = np.where(np.diff(np.sign(seasonal)))[0]

    # 计算波峰和波谷之间的周期
    peak_intervals = np.diff(zero_crossings)

    # 取平均波峰间距作为周期估计
    if len(peak_intervals) > 1:
        estimated_period = (
            np.mean(peak_intervals) * 2
        )  # 乘以2是因为零交点只记录了波峰到波谷或波谷到波峰的间隔
    else:
        estimated_period = "无法识别周期，数据可能无明显周期性"

    print(f"识别的周期为: {estimated_period} 个时间单位")

    # # 绘制季节性成分，调整时间轴
    # plt.figure(figsize=(10, 6))
    # plt.plot(seasonal)

    # plt.title("周期性成分 (Seasonal Component)")
    # plt.xlabel("时间 (Time)")
    # plt.ylabel("周期性")
    # plt.show()


if __name__ == "__main__":
    cal_period_month()
# 这个的输入是每天所有商品的总销量 分析的是销量的规律 分析出了销量变化的总体趋势 以及销量是以7天为周期
# 我觉得主要是要解释这个算法
